package utils;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.widget.PopupWindow;

import com.shishi.tech.paipai.application.BaseApplication;

import java.util.HashMap;
import java.util.Map;

import log.LogManager;

public class VoiceUtil implements MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaRecorder.OnErrorListener, MediaPlayer.OnBufferingUpdateListener {
    private String voicePath = "";

    private int flag = 0;

    private static VoiceUtil voiceUtil = null;
    private MediaRecorder mRecorder = null;
    private MediaPlayer mPlayer = null;
    private boolean isRecordVoice = false;

    private long updateTime;
    private Context mContext;

    public OnVoiceRecordFinishListener onVoiceRecordFinishListener;
    public OnVoicePlayFinishListener onVoicePlayFinishListener;

    private Handler handler = new Handler(Looper.getMainLooper()); //计时
    private Runnable runnable;

    private int totalTime; //录制长度
    private long totalVolume;//累加的音频幅度，用以检查录音权限
    private int CHECK_TIMEPOINT = 1000;//检查录音权限的时间点
    private int CHECK_SIZE = 2 * 1024;//检查权限时的文件大小值
    private boolean isRecording = false;
    private PopupWindow pop;

    /**
     * 播放完成
     *
     * @param mp
     */
    @Override
    public void onCompletion(MediaPlayer mp) {
        stopAuPlayVoice();
        //EventBus.getDefault().post(new FindEvent(FindEvent.FIND_ADVOICE_STOP, new AdVoicePlayBean(voicePath, 0)));
    }

    @Override
    public void onError(MediaRecorder mr, int what, int extra) {
        isRecordVoice = false;
        stopRecordVoice();
    }

    /**
     * 缓冲进度
     *
     * @param mp
     * @param percent
     */
    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        LogManager.getLogger().d("VoiceUtil===", "onBufferingUpdate");
    }

    /**
     * 资源已经准备
     *
     * @param mp
     */
    @Override
    public void onPrepared(MediaPlayer mp) {
        LogManager.getLogger().d("VoiceUtil===", "onPrepared");
        if (mPlayer.isPlaying()) {

        }
    }

    public interface OnVoiceRecordFinishListener {
        void onVoiceRecordFinish();
    }

    public interface OnVoicePlayFinishListener {
        void onVoicePlayFinish(Object object);
    }

    private VoiceUtil() {
        super();
    }

    public static VoiceUtil getInstance() {
        if (null == voiceUtil) {
            synchronized (VoiceUtil.class) {
                VoiceUtil temp = voiceUtil;
                if (temp == null) {
                    temp = new VoiceUtil();
                    voiceUtil = temp;
                }
            }
        }
        return voiceUtil;
    }

    /**
     * 计时CHECK_TIMEPOINT 毫秒，用以检查录音权限是否开启
     */
    private void timing() {
        totalTime = 0;
        totalVolume = 0;
        runnable = new Runnable() {
            @Override
            public void run() {
                if (!isRecording) {
                    handler.removeCallbacksAndMessages(null);
                } else {
                    if (totalTime == CHECK_TIMEPOINT) {
                        handler.removeCallbacksAndMessages(null);
                        LogManager.getLogger().w("totalVolume-CHECK_TIMEPOINT", "totalVolume==>" + totalVolume);
                        if (totalVolume == 0) {
                            checkAudioEnable();
                        }
                    } else if (null != mRecorder) {
                        totalVolume += mRecorder.getMaxAmplitude();
                        LogManager.getLogger().w("totalVolume==>", "" + totalVolume);
                        totalTime += 200;
                        handler.postDelayed(this, 200);
                    }
                }
            }
        };
        handler.postDelayed(runnable, 200);
    }

    /**
     * 检查录音文件大小
     */
    public void checkFileSize(Activity activity) {
        LogManager.getLogger().w("totalVolume-CHECK_SIZE", "FileSizes==>" + FileUtil.getFileSizes(getVoicePath()));
        if (FileUtil.getFileSizes(getVoicePath()) <= CHECK_SIZE) {
            checkAudioFileSize(activity);
        }
    }


    private void checkAudioFileSize(Activity activity) {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setTitle("录音文件保存出错");
        builder.setMessage("请检查录音权限后重试");
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (pop != null) {
                    pop.dismiss();
                }
            }
        });
        builder.show();
    }

    /**
     * 检查语音录制的权限
     */
    private void checkAudioEnable() {
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle("录音权限未打开");
        builder.setMessage("请打开录音权限后重试");
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (pop != null) {
                    pop.dismiss();
                }
            }
        });
        builder.setCancelable(false);
        builder.show();
    }

    /**
     * 初始化时  先调用该方法 获取权限
     */
    public void initRecordPermission() {
        try {
            mRecorder = new MediaRecorder();
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        } catch (Exception e) {
            checkAudioEnable();
        }
    }

    /**
     * 录音
     *
     * @param name
     */
    public boolean startRecordVoice(Context context, @Nullable PopupWindow pop, String name) {
        this.pop = pop;
        isRecording = true;
        this.mContext = context;
        if (isRecordVoice) {
            stopRecordVoice();
            return false;
        } else {
            this.voicePath = name;
            flag = 0;

            isRecordVoice = true;
            if (!Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
                return false;
            }

            try {
                if (mRecorder == null) {
                    mRecorder = new MediaRecorder();
                    mRecorder.setOnErrorListener(this);
                } else {
                    mRecorder.reset();
                }

                //                mRecorder.reset();
                mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

                //                    mRecorder.setAudioChannels(1);
                //                    mRecorder.setAudioEncodingBitRate(16);
                //                    mRecorder.setAudioSamplingRate(8000);

                mRecorder.setMaxDuration(60000);
                mRecorder.setOutputFile(name);

                mRecorder.setOnErrorListener(this);

                mRecorder.prepare();
                mRecorder.start();
                flag = 1;

                updateTime = FileUtil.getCurrentTimeMillis();
                timing();
            } catch (Exception e) {
                isRecordVoice = false;
                if (null != mRecorder) {
                    //                    mRecorder.stop();//魅族权限问题
                    //                    mRecorder.release();
                    mRecorder = null;
                }
                checkAudioEnable();
                return false;
            }
        }
        return true;
    }

    public void seekToProgress(int progress) {
        mPlayer.seekTo(progress);
    }

    public void switchPlayState() {
        if (mPlayer != null) {
            if (mPlayer.isPlaying()) {
                mPlayer.pause();
            } else {
                mPlayer.start();
            }
        }
    }

    /**
     * 停止录音
     */
    public void stopRecordVoice() {
        isRecording = false;
        freeMediaRecordResource();
    }

    /**
     * 储存异步播放器TxAsyncPlayer
     */
    private static Map<String, TxAsyncPlayer> asyncPlayers = new HashMap();

    /**
     * 是否正在播放
     */
    public boolean isPlayVoice = false;

    public TxAsyncPlayer getCurrentPlayer(String tag) {
        return asyncPlayers.get(tag);
    }

    /**
     * @param context        Your application's context.
     * @param uri            The URI to play.
     * @param looping        Whether the audio should loop forever.
     * @param tag            a string to use for debugging and mark
     * @param onPlayListener PlayListener for monitor the play process
     */
    public void startVoice(Context context, Uri uri, boolean looping, String tag, TxAsyncPlayer.OnPlayListener onPlayListener) {
        stopAllVoice();
        TxAsyncPlayer asyncPlayer = new TxAsyncPlayer(tag);
        asyncPlayers.put(tag, asyncPlayer);
        asyncPlayer.play(context, uri, looping, onPlayListener);
        isPlayVoice = true;
    }

    /**
     * @param tag the TxAsyncPlayer you want to stop
     */
    public synchronized void stopVoice(String tag) {
        LogManager.getLogger().i("TxAsyncPlayerTAG", tag);
        if (tag == null) {
            LogManager.getLogger().i("null is forbidden", "check your tag");
            return;
        }
        TxAsyncPlayer asyncPlayer = asyncPlayers.get(tag);
        isPlayVoice = false;
        if (asyncPlayer != null && asyncPlayer.mState == TxAsyncPlayer.PLAY) {
            LogManager.getLogger().i("TxAsyncPlayermState", asyncPlayer.mState + "");
            asyncPlayer.stop();
            asyncPlayer.onPlayListener.onFinish(false);
        } else {
            LogManager.getLogger().i("no asyncPlayer find", "not find this asyncPlayer");
        }
    }

    /**
     * stop all player
     */
    public void stopAllVoice() {
        for (Map.Entry<String, TxAsyncPlayer> entry : asyncPlayers.entrySet()) {
            stopVoice(entry.getKey());
        }
        asyncPlayers.clear();
    }

    /**
     * 播放声音
     *
     * @param path
     */
    public void startPlayVoice(String path, OnVoicePlayFinishListener onVoicePlayFinishListener) {
        if (mPlayer != null) {
            if (mPlayer.isPlaying()) {
                stopAuPlayVoice();
                mPlayer = new MediaPlayer();
                if (path.equals(voicePath))
                    return;
            }
        }
        if (null == mPlayer) {
            mPlayer = new MediaPlayer();
        }
        mPlayer.reset();
        mPlayer.setOnCompletionListener(this);
        mPlayer.setOnBufferingUpdateListener(this);
        mPlayer.setOnPreparedListener(this);
        this.onVoicePlayFinishListener = onVoicePlayFinishListener;
        try {
            mPlayer.setDataSource(path);
            mPlayer.prepare();
            mPlayer.start();
            voicePath = path;
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
    }

    /**
     * 播放 在暂停/播放的状态切换
     */
    public void setVoicePause() {
        if (mPlayer.isPlaying()) {
            mPlayer.pause();
        } else {
            mPlayer.start();
        }
    }

    /**
     * 检测正在播放的语音文件 是否跟当前文件路径一直
     *
     * @param path
     * @return
     */
    public boolean isEqualsPlayPath(String path) {
        if (TextUtils.isEmpty(path) || TextUtils.isEmpty(voicePath))
            return false;
        return path.equals(voicePath);
    }

    /**
     * 播放完成/强制停止
     */
    public void stopAuPlayVoice() {
        if (null != onVoicePlayFinishListener) {
            onVoicePlayFinishListener.onVoicePlayFinish(TextUtils.isEmpty(voicePath) ? "" : voicePath);
        }
        freeMediaPlayerResource();
    }

    /**
     * 释放MediaRecord 资源
     */
    public void freeMediaRecordResource() {
        if (null != mRecorder && isRecordVoice) {
            try {
                isRecordVoice = false;

                mRecorder.stop();
                mRecorder.reset();
                mRecorder.release();
                mRecorder = null;
            } catch (Exception e) {
                LogManager.getLogger().w("freeMediaRecordResource===", "freeMediaRecordResource==failed");
                return;
            }
        }
    }

    /**
     * 释放MediaPlayer 资源
     */
    public void freeMediaPlayerResource() {
        if (null != mPlayer) {
            mPlayer.stop();
            mPlayer.release();
            mPlayer = null;
        }
    }

    /**
     * 音频振幅
     *
     * @return
     */
    public int getAmplitude() {
        if (mRecorder != null)
            switch ((int) (mRecorder.getMaxAmplitude() / 2700.0)) {
                case 0:
                    return 0;
                case 1:
                    return 1;
                case 2:
                case 3:
                    return 2;
                case 4:
                case 5:
                    return 3;
                case 6:
                case 7:
                    return 4;
                case 8:
                case 9:
                    return 5;
                case 10:
                case 11:
                    return 6;
                default:
                    return 7;
            }
        else
            return 0;
    }

    public String getVoicePath() {
        return voicePath;
    }

    public void setVoicePath(String voicePath) {
        this.voicePath = voicePath;
    }

    public MediaRecorder getmRecorder() {
        return mRecorder;
    }

    public boolean isRecordVoice() {
        return isRecordVoice;
    }

    public boolean isPlayVoive() {
        //        return null == mPlayer? false : mPlayer.isPlaying();
        AudioManager mAudioManager = (AudioManager) BaseApplication.getInstance().getBaseContext().
                getSystemService(Context.AUDIO_SERVICE);
        return mAudioManager.isMusicActive();
    }
}
